package src

import (
	"encoding/json"
	"net/http"
	"strconv"
	"time"

	"gitee.com/haifengat/goctp/v2"
	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
	"gopkg.in/antage/eventsource.v1"
)

var sseID = 0
var es eventsource.EventSource

func initSSE(g *gin.RouterGroup) {
	if es != nil {
		return
	}
	es = eventsource.New(&eventsource.Settings{
		Timeout:        5 * time.Second,
		CloseOnTimeout: true,
		IdleTimeout:    365 * 24 * time.Hour, // 年
		Gzip:           true,
	},
		func(req *http.Request) [][]byte {
			return [][]byte{
				[]byte("X-Accel-Buffering: no"),
				[]byte("Access-Control-Allow-Origin: *"), // 解决跨域问题
			}
		})
	g.GET("/sse", func(ctx *gin.Context) {
		es.ServeHTTP(ctx.Writer, ctx.Request)
	})
}

// sseBar 推送K线
func sseBar(bar *Bar) {
	if _, ok := subInstrument[bar.InstrumentID]; !ok { // 未订阅,不发送
		return
	}
	bs, err := json.Marshal(bar)
	if err != nil {
		logrus.Error("json bar: ", err)
		return
	}
	sseID++
	es.SendEventMessage(string(bs), "bar", strconv.Itoa(sseID))
	// logrus.Info("send tail No.", sseID)
}

// sseTick 推送K线
func sseTick(tick *goctp.CThostFtdcDepthMarketDataField) {
	if _, ok := subInstrument[tick.InstrumentID.String()]; !ok { // 未订阅,不发送
		return
	}
	t := &Tick{
		TradingDay:      TradingDayType(tick.TradingDay.String()),
		InstrumentID:    tick.InstrumentID.String(),
		ExchangeID:      ExchangeIDType(tick.ExchangeID.String()),
		LastPrice:       float64(tick.LastPrice),
		OpenPrice:       float64(tick.OpenPrice),
		HighestPrice:    float64(tick.HighestPrice),
		LowestPrice:     float64(tick.LowestPrice),
		Volume:          int(tick.Volume),
		Turnover:        float64(tick.Turnover),
		OpenInterest:    float64(tick.OpenInterest),
		SettlementPrice: float64(tick.SettlementPrice),
		UpperLimitPrice: float64(tick.UpperLimitPrice),
		LowerLimitPrice: float64(tick.LowerLimitPrice),
		UpdateTime:      tick.UpdateTime.String(),
		UpdateMillisec:  int(tick.UpdateMillisec),
		BidPrice1:       float64(tick.BidPrice1),
		BidVolume1:      int(tick.BidVolume1),
		AskPrice1:       float64(tick.AskPrice1),
		AskVolume1:      int(tick.AskVolume1),
		AveragePrice:    float64(tick.AveragePrice),
	}
	t.Fix()
	bs, err := json.Marshal(t)
	if err != nil {
		logrus.Error("json tick: ", err)
		return
	}
	sseID++
	es.SendEventMessage(string(bs), "tick", strconv.Itoa(sseID))
	// logrus.Info("send tail No.", sseID)
}

func sseOrder(ord *OrderField) {
	bs, err := json.Marshal(ord)
	if err != nil {
		logrus.Error("json bar: ", err)
		return
	}
	sseID++
	es.SendEventMessage(string(bs), "order", strconv.Itoa(sseID))
	// logrus.Info("send tail No.", sseID)
}

func sseTrade(trade *TradeField) {
	bs, err := json.Marshal(trade)
	if err != nil {
		logrus.Error("json bar: ", err)
		return
	}
	sseID++
	es.SendEventMessage(string(bs), "trade", strconv.Itoa(sseID))
	// logrus.Info("send tail No.", sseID)
	ssePosition(new(PositionField)) // 通知客户端有更新
}

func ssePosition(pos *PositionField) {
	bs, err := json.Marshal(pos)
	if err != nil {
		logrus.Error("json bar: ", err)
		return
	}
	sseID++
	es.SendEventMessage(string(bs), "position", strconv.Itoa(sseID))
	// logrus.Info("send tail No.", sseID)
}
